<TITLE>GDD Reference Manual</TITLE>
<P><h1>GDD Reference Manual</h1>

<a href="gddref.html#gdd">gdd</a><br>
<a href="gddref2.html#gddAtomic">gddAtomic</a><br>
<a href="gddref2.html#gddScalar">gddScalar</a><br>
<a href="gddref2.html#gddContainer">gddContainer</a><br>
<a href="gddref2.html#gddApplicationTypeTable">gddApplicationTypeTable</a><br>
<P>
<a href="gddref2.html#gddDestructor">gddDestructor</a><br>
<a href="gddref2.html#gddBounds">gddBounds</a><br>
<a href="gddref2.html#gddBoundsxD">gddBounds1D gddBounds2D gddBounds3D</a><br>
<a href="gddref2.html#gddCursor">gddCursor</a><br>
<a href="gddref2.html#gddSemaphore">gddSemaphore</a><br>
<a href="gddref2.html#gddIntLock">gddIntLock</a><br>
<P>
<a href="gddref2.html#aitConvert">aitConvert</a><br>
<a href="gddref2.html#aitTimeStamp">aitTimeStamp</a><br>
<a href="gddref2.html#aitString">aitString</a><br>
<a href="gddref2.html#aitTypes_h">aitTypes/aitEnums</a><br>
<P>
<a href="gddref2.html#gddNewDel_h">new/delete Free List Management</a><br>
<a href="gddref2.html#gddApps_h">Application Type Code Index Labels</a><br>
<a href="gddref2.html#gddErrorCodes_h">gddStatus - Error Codes</a><br>
<P>
<a href="gddref2.html#dbMapper_h">DBR To ait Conversion Functions</a><br>
<a href="gddref2.html#dbMapper_h">gddMakeMapDBR</a><br>
<a href="gddref2.html#dbMapper_h">gddMapDbr</a><br>
<a href="gddref2.html#dbMapper_h">gddAitToDbr</a><br>
<a href="gddref2.html#dbMapper_h">gddDbrToAit</a><br>
<P>
<a href="gdd.html">User's Guide</a><br>

<hr><h2><a name="gdd">gdd</a></h2>
Main GDD library base class.  A fundemental class for describing a scalar
value, an array or an array of GDDs know as a container.  See the User's
Guide for a detailed explanation.

<p>#include "gdd.h"<p>

<b><i>gdd(void)</i></b><br>
<b><i>gdd(gdd*)</i></b><br>

Construct a new gdd that is empty or that is a copy of another gdd instance.

<p>
<b><i>gdd(int ApplicationType);</i></b><br>
<b><i>gdd(int ApplicationType, aitEnum PrimitiveType);</i></b><br>
<b><i>gdd(int ApplicationType, aitEnum PrimitiveType, int Dimension);</i></b><br>
<b><i>gdd(int ApplicationType, aitEnum PrimitiveType, int Dimension,
	aitUint32* ElementCounts);</i></b><br>

Construct a new gdd, describing various data properties.  If <I>Dimension</I>
is greater that zero, then <I>ElementCounts</I> is an array with Dimension
number of elements in it.  Each element of the array describes how many
elements are in that dimension.  The ElementCount information is used to
initialize the bounds of a GDD.

<p>
<b><i>unsigned applicationType(void) const;</i></b><br>
<b><i>aitEnum primitiveType(void) const;</i></b><br>
<b><i>unsigned dimension(void) const;</i></b><br>
<b><i>gddStatus changeType(int AppType, aitEnum PrimType) const;</i></b><br>

Return the GDDs application type code.  Return the type of data stored in the
GDD.  Remember that the application type code is arbitrarily set by the user
and it imposes a user-level meaning to the data.  The primitive type code
is generally a compiler supported data type with a predetermined size, such
as double, float, short, int, etc..  Return the dimension of the data in
the GDD; zero indicates a scalar.  ChangeType() allows for a GDD that is
a scalar or a GDD with an undefined primitive type to be converted to
a new primitive type and application type code.  Changes in this case
are safe.

<DL>changeType() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorTypeMismatch - GDD is not scalar or primitive type valid
	</DL>
</DL>

<p>
<b><i>gddDestructor* destructor(void) const;</i></b><br>
<b><i>gddStatus registerDestructor(gddDestructor*);</i></b><br>
<b><i>gddStatus replaceDestructor(gddDestructor*);</i></b><br>

Methods for manipulating the user-defined GDD destructor.  Destructor()
just returns a reference to the GDDs destructor.  RegisterDestructor()
installs a destructor in the GDD if one is not already present.
ReplaceDestructor() forces a GDDs destructor to be replaced.

<DL>registerDestructor() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorAlreadyDefined - gddDestructor already registered in GDD
	</DL>
</DL>

<p>
<b><i>const gddBounds* getBounds(void) const;</i></b><br>
<b><i>const gddBounds* getBounds(int dimension) const;</i></b><br>
<b><i>gddStatus getBound(unsigned dim_to_get, aitIndex& first, aitIndex& count);</i></b><br>
<b><i>gddStatus setBound(unsigned dim_to_set, aitIndex first, aitIndex count);</i></b><br>

Retrieve the bounds array from the GDD or get a gddBounds for a 
particular dimension with the first two methods listed.  Get and set
information contained within the bounds structure of a GDD.  Dimension
bounds in the GDD library are always expressed as (first,count), see the
User's guide for details.

<DL>getBound() and setBound return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorOutOfBounds - requested dimension does not exist
	</DL>
</DL>

<p>
<b><i>void dump(void);</i></b><br>

Print out all the information contained in the fields of a GDD in a 
useful,readable fashion.  Good tool for learning about the information
a GDD holds.

<p>
<b><i>void setPrimType(aitEnum PrimitiveEnumType);</i></b><br>
<b><i>void setApplType(int ApplicationTypeCode);</i></b><br>

Force the GDD to change the primitive type of the data it describes.
Changing the primitive type code is generally an unnatural thing to do.
Force a GDD to change the application type, which effectively changes
the high-level meaning of the data held within the GDD.

<p>
<b><i>void setDimension(int);</i></b><br>

Describe the data a GDD hold in terms of a different dimension.  This call
does not alter the data, it does however deallocate bounds and reallocate
them to match the new dimension.  This call can really cause probably when
dealing with packed or flattened GDDs.  This operation is not advisable
is simple applications, users are better off deleting the GDD and
creating one that suites the data in mosts instances.

<p>
<b><i>void* dataAddress(void) const;</i></b><br>
<b><i>void* dataPointer(void) const;</i></b><br>
<b><i>void* dataPointer(aitIndx element_offset) const;</i></b><br>

All of these methods are designed to give the user general access to
the data within a GDD.  These calls are meant to be used internally and
by specialized libraries.  The last method listed will give the starting
address of a portion of a simple single dimensional array given an
element offset.

<p>
<b><i>void destroyData(void);</i></b><br>

If the GDD is describing an array and a destructor is present, then run
the destructor.  If the GDD is a container, then run the destructor
giving the argument to the run() function the address of the container
rather then the data that the GDD holds.

<p>
<b><i>gddStatus reset(aitEnum primtype,int dimension, aitIndex* dim_counts);</i></b><br>
<b><i>gddStatus clear(void);</i></b><br>
<b><i>gddStatus clearData(void);</i></b><br>

The clear() method completely clears out a GDD, this includes removing
bounds information, running destructors, and resetting every field in a 
GDD to invalid.  The clearData() method keeps the GDD information intact,
but runs the data destructors and clears out the data field.  Reset()
first runs clear() on the GDD, and then resets the primitive type, dimension,
and bounds information, the appliacation type code remains the same.

<DL>clear() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if GDD is flattened or managed
	</DL>
</DL>
<DL>clearData() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if GDD is a container
	</DL>
</DL>
<DL>reset() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if GDD is flattened, managed, or a container
	</DL>
</DL>

<p>
<b><i>void getTimeStamp(struct timespec* const ts) const;</i></b><br>
<b><i>void getTimeStamp(aitTimeStamp* const ts) const;</i></b><br>
<b><i>void setTimeStamp(const struct timespec* const ts);</i></b><br>
<b><i>void setTimeStamp(const aitTimeStamp* const ts);</i></b><br>

Manipulate the time stamp field of the GDD using an aitTimeStamp structure
or a standard struct timespec.

<p>
<b><i>void setStatus(aitUint32);</i></b><br>
<b><i>void getStatus(aitUint32&);</i></b><br>

Use the status field of the GDD is a general fashion.  The status field
is assigned a value arbitrarily by the user.

<p>
<b><i>void setStat(aitUint16);</i></b><br>
<b><i>void setSevr(aitUint16);</i></b><br>
<b><i>aitUint16 getStat(void) const;</i></b><br>
<b><i>aitUint16 getSevr(void) const;</i></b><br>
<b><i>void setStatSevr(aitInt16 stat, aitInt16 sevr);</i></b><br>
<b><i>void getStatSevr(aitInt16& stat, aitInt16& sevr);</i></b><br>

Manipulate the status field of a GDD as a combination 16-bit status
and 16-bit severity field.

<p><b><i>size_t getTotalSizeBytes(void) const;</i></b><br>

Return the total size in bytes of the entire GDD including all the data
it references and bounds array.  This is the length of the GDD and all
the items it references.

<p><b><i>size_t getDataSizeBytes(void) const;</i></b><br>
Return the total size in bytes of the data that the GDD contains or references.

<p><b><i>aitUint32 getDataSizeElements(void) const;</i></b><br>
Return the number of elements that the GDD describes.

<p><b><i>gddStatus copyData(const gdd* dd);</i></b><br>
Copy the data from gdd dd to this gdd.  This function resets the bounds, the
dimension, the primitive type and the application.  In addition, it
allocates a buffer large enough to hold all the data from dd and copies
the data from dd to the new buffer and references it into this gdd.  A new
standard gddDestructor is allocated and registered into this GDD that
will be used to delete the newly created data buffer.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if this GDD is flattened, managed, or a container
	</DL>
</DL>

<p><b><i>gddStatus copyInfo(gdd* dd);</i></b><br>
Copy the data description fields from dd to this gdd.  The primitive type, 
application type, dimension, and bounds are copied.  This gdd is cleared
completely before the information from dd is copied.  If dd is a container,
then this gdd becomes a container which looks just like dd without any
data.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if this GDD is flattened or managed
	</DL>
</DL>

<p>
<b><i>gddStatus copy(gdd* dd);</i></b><br>
<b><i>gddStatus dup(gdd* dd);</i></b><br>
Copy() does everything that copyInfo() does, but also copies the data just as
copyData() would.  Dup() does everything that copyInfo() does, but references
the data that dd contains.  If dd has a user registered destructor, the this
gdd registers the same destructor instance and bumps up the destructor
reference count.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if this GDD is flattened or managed
	</DL>
</DL>

<p>
<b><i>size_t flattenWithAddress(void* buf, size_t buf_size,
	aitIndex* total_dds);</i></b><br>
<b><i>size_t flattenWithOffsets(void* buf, size_t buf_size,
	aitIndex* total_dds);</i></b><br>
These functions pack this gdd instance into buffer buf.  Both functions
return the amount of space in bytes used by this gdd.  The function will
not go beyond buf_size.  The parameter total_dds will be modified to
reflect the total gdds packed into buf.  Flattened GDDs can be
directly indexed, the total_dds variable indicates the number of elements
in the gdd array starting at buf.  This function can pack scalar GDDs,
atomic GDDs, or container GDDs recursively.  The organization of the
buffer is as follows: All GDDs are first, all bounds information follows,
and array data for all the GDDs follow the bounds.  The flattenWithAddress()
method is the standard way to produce a useable, packed GDD.  The method
flattenWithOffsets() puts offsets in where address normally go in GDD
fields.  This function allows GDD to be transfered from one machine or
address space to another when used in conjunction with
convertOffsetsToAddress() and convertAddressToOffsets().

<p>
<b><i>gddStatus convertAddressToOffsets(void);</i></b><br>
<b><i>gddStatus convertOffsetsToAddress(void);</i></b><br>
These functions run through this gdd and convert all addressing information
from offsets (from zero) to real addresses or real addresses to offsets.
These function work recursively with container type GDDs.  The function
convertAddressToOffsets() can only work with a GDD that is flattened.
<DL>convertAddressToOffsets() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if this GDD is not flattened
	</DL>
</DL>

<p>
<b><i>int isScalar(void) const;</i></b><br>
<b><i>int isAtomic(void) const;</i></b><br>
<b><i>int isContainer(void) const;</i></b><br>
Each return true to indicate the type of GDD that this is.

<p>
<b><i>int isManaged(void) const;</i></b><br>
<b><i>void markManaged(void);</i></b><br>
<b><i>void markUnmanaged(void);</i></b><br>
Manipulate the GDD managed state flag.  A managed GDD is managed by a
higher level facility such as the application type table.  Managed GDDs
have special properties, such as a destructor that knows how to place the
GDD back on a free list buffer pool.  All GDDs retrieved from the 
application type table that are associated with a prototype will be
managed.  Certain copy operations are not allows on managed GDDs.  See
the User's Guide for further details.

<p><b><i>int isFlat(void) const;</i></b><br>
Discover if this GDD has been flattened.

<p>
<b><i>int isLocalDataFormat(void) const;</i></b><br>
<b><i>int isNetworkDataFormat(void) const;</i></b><br>
<b><i>void markLocalDataFormat(void);</i></b><br>
Indicate that data stored in the GDD is in a local byte order or floating
point format.  Discover if data in the GDD is in local data format.

<p>
<b><i>int isConstant(void) const;</i></b><br>
<b><i>void markConstant(void);</i></b><br>
Control the constant state flag of this GDD.  The data in a constant GDD
cannot be changed.

<p>
<b><i>int isNoRef(void) const;</i></b><br>
<b><i>gddStatus noReferencing(void);</i></b><br>
<b><i>gddStatus reference(void);</i></b><br>
<b><i>gddStatus unreference(void);</i></b><br>
Control and manipulate the reference counts of a GDD.  Reference() bumps
up the GDD reference count.  Unreference() decrements the reference count of
this GDD, if the reference count drops to zero, then the GDD is deleted.
NoReferencing() locks the GDD reference count and disallows further
referencing of this GDD.
<DL>noReferencing() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if this GDD has reference count > 1 already
	</DL>
</DL>
<DL>reference() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - if referencing is not allowed on this GDD
	</DL>
</DL>
<DL>unreference() return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorUnderflow - if reference count is zero before decrement
	</DL>
</DL>

<p><b><i>gddStatus genCopy(aitEnum dtype, const void* buffer);</i></b><br>
Generalized copy routine that takes data from buffer of type dtype and
puts it into this gdd.  If this gdd is a scalar, then one element from
buffer is converted to the primitive type of the GDD and copied in.  If
this GDD is an array, then the number of elements copied is determined by
the bounds information stored in this GDD.  Is this GDD described an array,
but has no data buffer associated with it, then a new buffer is
allocated which is the size the bounds describes, and the data from
parameter buffer is converted to the GDD primitive type and put into
the newly created GDD buffer.  Not a commonly used function.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorTypeMismatch - If this GDD is a container
	</DL>
</DL>

<p>
<b><i>void adjust(gddDestructor* dest, void* dbuf, aitEnum dtype);</i></b><br>
This function runs the destructor in this GDD if present, effectively
destroying the data is this GDD.  The parameter dest becomes the new
destructor, dbuf becomes the GDD's referenced data buffer, and dtype
becomes the new primitive type for this GDD.  Not a commonly used function.

<p>
<b><i>void set(aitEnum dtype, void* dbuf);</i></b><br>
<b><i>void get(aitEnum dtype, void* dbuf);</i></b><br>
Generalized functions for copying the first element of this GDD into and out
from dbuf.  Set() takes one element pointed to by dbuf of type dtype and
converts it to this GDD primitive type and copies it to this GDDs data field.
Get() takes one element of this GDD's data field and convert it to dtype and
copies it into dbuf.  Not a commonly used function.

<p><b><i>void getRef(ait_xxxxx*& dbuf);</i></b><br>
Standard way to get access to the data buffer an array-type GDD references.
There is one of these methods for each of the supported ait types.  The
dbuf parameter is modified to point to the GDD's data buffer.  There is a
danger here.  Data pointers in a GDD are stored as void*.  The primitive
type indicates the true type of data.  These methods can be used to 
cast the data pointer to any of the ait types, completely ingoring the
primitive type code.  The idea here is that the user will dicover the
correct primitive type and call the correct method.

<p>
<b><i>void putRef(ait_xxxxx* dbuf, gddDestructor dest=NULL);</i></b><br>
<b><i>void putRef(const ait_xxxxx* dbuf, gddDestructor dest=NULL);</i></b><br>
<b><i>void putRef(void* dbuf,aitEnum code,gddDestructor dest=NULL);</i></b><br>
Standard way to reference data into a GDD and optionally supply a destructor.
These methods are designed to work with array or atomic type GDDs.
There is one of these methods for each of the support ait types.  All these
methods invoke adjust() to do the work with the correct aitEnum type code.
See adjust() for further details.  The second method listed marks the GDD
state as constant.

<p><b><i>void getConvert(ait_xxxxx& dbuf);</i></b><br>
Standard way to retreive scalar data from this GDD.  There is one of these
methods for each of the ait types.  The data in the GDD will be converted
from it's primitive type to the ait_xxxxx data type and placed into dbuf.
These methods invoke "void get(aitEnum dtype, void* dbuf)".

<p><b><i>void putConvert(ait_xxxxx dbuf);</i></b><br>
Standard way to place a scalar value into a GDD.  There is one of these
methods for each of the ait types.  The data will be converted from 
ait_xxxxx to the GDD's primitive type and placed into the data field.
These methods invoke set().

<p><b><i>gddStatus put(const ait_xxxxx* const dbuf);</i></b><br>
Standard way to copy data from dbuf of type ait_xxxxx into this GDD's buffer.
There is one of these methods for each of the ait types.
These methods invoke genCopy() with proper arguments, see genCopy() for
further details.  The return codes of these methods are the same as
genCopy().

<p><b><i>gddStatus put(ait_xxxxx dbuf);</i></b><br>
Standard way to place a scalar value into this scalar GDD and reset the
There is one of these methods for each of the ait types.
primtive type to match ait_xxxxx.  No conversions take place in these
methods, they are meant to adjust the primitive type.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotAllowed - If this GDD is not a scalar
	</DL>
</DL>

<p><b><i>gddStatus put(const gdd* dbuf);</i></b><br>
Put the data from dbuf into this GDD.  Resets all information in this GDD
to match dbuf.
<DL>return codes:
	<DL>
		<DT>0 - Success
		<DT>gddErrorNotSupported - If this GDD or dbuf is a container.  Also if
		dbuf has dimension greater than one.
		<DT>gddErrorOutOfBounds - Attempting to copying more dbuf elements
		into this GDD then this GDD can hold.
		<DT>gddErrorNotAllowed - If this GDD has no allocated data but has a
      destructor registered.
	</DL>
</DL>

<p>
<b><i>void get(ait_xxxxx* dbuf);</i></b><br>
<b><i>void get(void* dbuf, aitEnum dtype);</i></b><br>
Standard way to retrieve array data from this GDD into dbuf with 
primitive type conversion.
There is one of these methods for each of the ait types.
The amount of data copied out of this GDD depends on the primitive type
(for size of element information), and the dimension/bounds for the
total element count.  These methods will convert the data from the GDDs
primitive type to the ait_xxxxx type as the copy is taking place.
Depending on the conversion, the size required by dbuf may be more or
less then the size of this GDD's data buffer.

<p><b><i>void get(ait_xxxxx& dbuf);</i></b><br>
Standard way to get scalar data out of this GDD and perform data conversions
from this GDD primitive type to ait_xxxxx.
There is one of these methods for each of the ait types.
These methods simply invoke "void get(aitEnum dtype, void* dbuf)", see this
method for further details.

<p><b><i>gdd& operator=(ait_xxxxx* v);</i></b><br>
Convenience methods so the equal operator can be used.  Same as putRef(...)
methods.

<p><b><i>gdd& operator=(ait_xxxxx v);</i></b><br>
Convenience methods so the equal operator can be used.  Same as put(...)
methods.

<p><b><i>operator ait_xxxxx*(void) const;</i></b><br>
<p><b><i>operator ait_xxxxx(void) const;</i></b><br>
Convenience methods so casting can be done from this GDD to any supported
ait_xxxxx pointer variable.  Same as getRef(...) and get(...) methods.

<hr>Argonne National Laboratory 
<a href="http://www.aps.anl.gov/asd/controls/epics_copyright.html">Copyright</a>
Information<br>
<address>Jim Kowalkowski (jbk@aps.anl.gov)</address> updated 4/12/95

